#include <allegro.h>
#include <assert.h>
#include "dark_blit.h"

void dark_blit (BITMAP *source, BITMAP *dest, 
                int source_x, int source_y, int dest_x, int dest_y, 
                int width, int height, int darkness)
{
	assert(source != NULL);
	assert(dest   != NULL);
	assert(source_x >= 0);
	assert(source_y >= 0);
	assert(source_x + width  <= source->w);
	assert(source_y + height <= source->h);
	assert(darkness >= 0);
	assert(darkness <= 255);
	
	const int TRANSPARENT = makecol(255, 0, 255);
	
	if (darkness <= 0) {
		masked_blit (source, dest, source_x, source_y, 
		             dest_x, dest_y, width, height);
		return;
	} else
	if (darkness >= 255) { // draw black only, but still mind the transparency
		int x1, x2, y1, y2;
		for (y1 = source_y, y2 = dest_y; y1 < source_y + height; y1++, y2++)
		for (x1 = source_x, x2 = dest_x; x1 < source_x + width ; x1++, x2++) {
			int pixel = _getpixel32 (source, x1, y1);
			if (pixel != TRANSPARENT) 
				putpixel (dest, x2, y2, 0);
		}
		return;
	}
	
	// clip dest
	int left = source_x - MIN(0, dest_x);
	int top = source_y - MIN(0, dest_y);
	int right = source_x + width - MAX(0, dest_x + width - dest->w);
	int bottom = source_y + height - MAX(0, dest_y + height - dest->h);
	
	int light = 255 - darkness;
	
	int x1, x2, y1, y2;
	for (y1 = top,  y2 = dest_y + top  - source_y; y1 < bottom; y1++, y2++)
	for (x1 = left, x2 = dest_x + left - source_x; x1 < right ; x1++, x2++) {
		int pixel = _getpixel32 (source, x1, y1);
		if (pixel != TRANSPARENT) {
			int col = makecol32 (getr(pixel) * light / 255,
			                     getg(pixel) * light / 255,
			                     getb(pixel) * light / 255);
			_putpixel32 (dest, x2, y2, col);
		}
	}
}
